

#ifndef _COROUTINE_H_
#define _COROUTINE_H_

#include <cstdint>
#include <functional>
#include <memory>
#include <mutex>
#include <ucontext.h>


namespace zepco {

/**
 * @brief Zephyr 负责协程的创建 让出 恢复 运行
 *
 */
class Zephyr : public std::enable_shared_from_this<Zephyr> {
  public:
    enum State {
        READY,
        RUNNING,
        TERM
    };
  private:
    Zephyr(); // 构造主协程
  public:
    Zephyr(std::function<void()> callback, uint32_t stacksize = 0, bool run_in_scheduler = true); // 构造子协程并这是入口函数
    ~Zephyr();

    void reset(std::function<void()> callback); // 重设入口函数 重新设置上下文 将TERM -> READY
    void resume();
    void yield();
    uint64_t getID() const {
        return m_id;
    }
    State getState() const {
        return m_state;
    }

  public:
    static void SetThis(Zephyr *z);  // 设置当前协程
    static std::shared_ptr<Zephyr> GetThis(); // 获取当前协程的shared_ptr
    static void SetSchedulerZephyr(Zephyr *z);  // 设置调度协程 默认主协程
    static uint64_t GetZephyrID();
    static void MainFunc(); // 协程的主函数

  private:
    uint64_t m_id;                      // 协程id
    uint32_t m_stacksize = 0;           // 协程栈大小
    State m_state = READY;              // 协程状态
    ucontext_t m_ctx;                   // 协程上下文
    void *m_stack = nullptr;            // 协程的栈指针
    std::function<void()> m_callback;   // 协程的回调函数
    bool m_runInScheduler;              // 是否将执行器交给调度协程
  public:
    std::mutex m_mtx;
};

}

#endif // _COROUTINE_H_